package application.LoginAndAdministrationModule;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import application.CommunicationModule.Communication;
import application.client.data.Address;

//Klasa przechowuj�ca informacje o aktualnie zalogowanym uzytkowniku oraz o warto�ciach wpisanych przez
//U�ytkownika w oknie logowania

public class Logging
{
	/////////////////////////////////////
	///////////	 fields   ///////////////
	/////////////////////////////////////
	
	boolean check_status; //pole przechowuj�ce informacje o tym czy u�ytkownik jest zalogowany
						  //True - zalogowany, False - niezalogowany, domy�lnie niezalogowany
	String login;		  
	String password;
	PersonData person;	  //obiekt przechowuj�cy potrzebne nam dane do logowania
	String encrypted_pass; // na poczatku puste, szyfrujemy w konstruktorze.
	PersonData loggedInUser; //przechowuje obiekt zalogowanego u�ytkownika
	byte rightOfLoggedInUser; //przechowuje uprawnienia zalogowanego u�ytkownika 0-user 1-worker 2-admin
	Szyfr koder;
    
	//Baza
	Communication connector;
	String query;
	ResultSet result;
	String url;
	String username;
	String pass;
	Connection conn;
	//
    PreparedStatement pstmt;
	
	/////////////////////////////////////
	///////////	 fields   ///////////////
	/////////////////////////////////////
	
	/////////////////////////////////////
	///////// consructors  //////////////
	/////////////////////////////////////
	public Logging()
	{
		this.rightOfLoggedInUser = -1;
		this.check_status=false;
		encrypted_pass="";
		pstmt = null;

	    koder = new Szyfr();
	    username = "inzynier_admin";
	    pass = "admin";
	    try {
			connector = new Communication(username, pass);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    conn = connector.getConnection();
	    
	}
	/////////////////////////////////////
	///////// consructors  //////////////
	/////////////////////////////////////
	
	/////////////////////////////////////
	///////// main method  //////////////
	/////////////////////////////////////
	
	//metoda zaloguj b�dzie uaktywniana po klikniciu zaloguj czyli przeszukamy baz� danych zweryfikujemy wpisane dane
	//Metoda ta zwraca obiekt zalogowanego u�ytkownika
	public boolean logIn(String login,String password) throws Exception
	{
			Integer id;
			
			if(check_status==true)
			{	//do późniejszej modyfikacji baza
				//System.out.println("Użytkownik, na którego próbujesz się zalogować jest już zalogowany");
			}
			
			//String encrypted_pass = encrypt(person.getPassword());
			if(fieldValidation(login,password))
			System.out.println("aa");
			
			id = findUser(conn,login,password);
	
			if(id==-1)
			{
				return false;
			}
			rightOfLoggedInUser = checkRightOfUser(conn,id);
			loggedInUser = getObjectOfPersonData(conn,id);
			

			check_status = true; //ustawiamy status na zalogowany
			return check_status; //zwracamy obiekt u�ytkownika kt�ry si� zalogowa�		
		}
		
		//Metoda ustawia pole, kt�re �wiadczy o zalogowaniu u�ytkownika na status: niezalogowany
		public boolean logOut()
		{
			check_status = false;
			return true;
		}
	/////////////////////////////////////
	///////// main method  //////////////
	/////////////////////////////////////
		
		
	/////////////////////////////////////
	//////// get/set methods ////////////
	/////////////////////////////////////
	
	public int getINumberOfUsers(Connection conn) throws SQLException //dzia�a
	{
		int x = -1;
		query = "SELECT count(*) FROM \"Users\"";
		pstmt = conn.prepareStatement(query);
		result = pstmt.executeQuery();
		result.next();
		x = result.getInt(1);
		return x;		
	}
	
	public PersonData getLoggedInUser()
	{
		return loggedInUser;
	}
	
	public byte getRightsOfLoggedInUser()
	{
		return rightOfLoggedInUser;
	}
	/////////////////////////////////////
	////////get/set methods ////////////
	/////////////////////////////////////
	
	/////////////////////////////////////
	////////// other methods ////////////
	/////////////////////////////////////
	
	public boolean isLogged()
	{
		if(check_status)return true;
		return false;
	}
	
	//metoda ta powinna dosta� 2 stringi wpisane w polach logowania, a nast�pnie sprawdza czy pola s� wype�nione
	private boolean fieldValidation(String login, String password)
	{
		if(login.isEmpty() || password.isEmpty()) return true;
		return false;
	}
	
	//ta metoda powinna znale�� u�ytkownika o podanym loginie i ha�le i zwr�ci� jego id
	//metoda zwraca warto�� -1 gdy nie znaleziono takiego u�ytkownika
	private Integer findUser(Connection conn, String login, String password) throws SQLException
	{
		Integer id;
		
		try
		{
			query = "SELECT id_user FROM \"Users\" WHERE login = ? AND password = ?";
		    pstmt = conn.prepareStatement(query);
		    pstmt.setString(1,login);
		    pstmt.setString(2,koder.encrypt (password));
		    result = pstmt.executeQuery();
		    if(result.next()==false) return -1;
		    id = result.getInt(1);
		    return id;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			pstmt.close();
		}
		
		return -1;
	}
	
	//Metoda ta zwraca uprawnienia u�ytkownika o podanym id
	//w razie problemu zwraca -1
	private byte checkRightOfUser(Connection conn, Integer id) throws SQLException
	{
		
		try
		{
			query = "SELECT rights FROM \"Users\" WHERE id_user = ?";
		    pstmt = conn.prepareStatement(query);
		    pstmt.setInt(1,id);
		    result = pstmt.executeQuery();
		    result.next();
		    rightOfLoggedInUser = (byte) result.getInt(1);
		    return rightOfLoggedInUser;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			pstmt.close();
		}
		
		return rightOfLoggedInUser;
	}
	
	//Metoda tworzy obiekt PersonData z danymi z bazy o u�ytkowniku o podanym id
	//zwraca null gdy p�jdzie co� nie tak
	private PersonData getObjectOfPersonData(Connection conn, Integer id) throws SQLException
	{
		PersonData p = new PersonData();
		
		try
		{
			int tmpId = 0;
			query = "SELECT * FROM \"Users\" WHERE id_user = ?";
		    pstmt = conn.prepareStatement(query);
		    pstmt.setInt(1,id);
		    result = pstmt.executeQuery();
		    while(result.next())  
			{ 
		    p.setId(Integer.parseInt(result.getString(1)));
		    p.setName(result.getString(2));
		    p.setSurname(result.getString(3));
		    p.setLogin(result.getString(4));
		    p.setPassword(result.getString(5));
		    p.setRights((byte) result.getInt(6));
		    tmpId = result.getInt(7);
		    p.seteMail(result.getString(8));
		    p.setphoneNumber(result.getString(9));
		    }
		    query = "SELECT * FROM \"Addresses\" WHERE id = ?";
		    pstmt = conn.prepareStatement(query);
		    pstmt.setInt(1,tmpId);
		    result = pstmt.executeQuery();
		    while(result.next())  
		    {
		    	p.setAddress(new Address(result.getString(2), result.getInt(3), result.getInt(4), result.getString(5), result.getString(6)));
		    }
		    
		    return p;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			pstmt.close();
		}
		
		return null;
	}
	
	public boolean changePassword(String login, String password, String newPassword) throws Exception
	{
		String codedPass = koder.encrypt(password);//kodujemy stare has�o
		
		try
		{
			query = "SELECT password FROM \"Users\" WHERE login = ?";
		    pstmt = conn.prepareStatement(query);
		    pstmt.setString(1,login);
		    result = pstmt.executeQuery();
		    result.next();
		    if(result.getString(1).equals(codedPass))
		    {
		    	query = "Update \"Users\" set password = ? where login = ?";
		    	pstmt = conn.prepareStatement(query);
		    	pstmt.setString(1,koder.encrypt(newPassword));
		    	pstmt.setString(2,login);
		    	pstmt.executeUpdate();
		    }
		    else
		    {
		    	return false;
		    }
		    return true;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			pstmt.close();
		}
		
		conn.close();
		return false;
	}
	/////////////////////////////////////
	//////////other methods ////////////
	/////////////////////////////////////
}